如果你是第一次阅读本文,你可能会对以下扫盲贴感兴趣:
有趣的练手项目《python3网络爬虫入门》
崔庆才|静觅的《Python爬虫学习系列教程》
Python selenium —— 一定要会用selenium的等待,三种等待方式解读
你可以还会关心以下的链接:
PhantomJS下载地址
谷歌浏览器驱动下载地址
你可能还想折腾比较前沿的headless:
Chrome 也支持 headless testing 啦
数据抓取
打开战狼2的短评网址,目标URL为 https://movie.douban.com/subject/26363254/comments?start=0&limit=20 ,每个电影都会有一个唯一的ID,这里战狼2的ID是26363254,start=0
表示评论从第0条开始,limit=20
表示每页显示20条短评。
打开审查元素中的Elements,找到我们感兴趣的评论区域,它们的结构体是这样的:

我们可以根据这个结构体的标签逐步剥离评论内容出来,先提取 < div class=”comment” > 标签块,再提取每个标签块里面的 < p class > 标签块的文字评论内容。python3代码如下:
单页评论抓取
1 2 3 4 5 6 7 8 9 10 11 12
| from urllib import request from bs4 import BeautifulSoup as bs requrl="https://movie.douban.com/subject/26363254/comments?start=0&limit=20" resp = request.urlopen(requrl) html_data = resp.read().decode('utf-8') soup = bs(html_data, 'html.parser') comment_div_lits = soup.find_all('div', class_='comment') eachCommentList = []; for item in comment_div_lits: if item.find_all('p')[0].string is not None: eachCommentList.append(item.find_all('p')[0].string) print(eachCommentList)
|
利用selenium爬取全部评论
selenium是自动化测试的工具,利用selenium和phantom可以模拟真实用户在无界面浏览器的网页浏览操作,类似你闭着眼睛不知疲倦上网而且能够一目百行。据闻使用无头浏览器phantom爬取豆瓣时,会出现输入验证码的障碍;测试中发现如果使用selenium+谷歌浏览器,非常顺利不需要输入验证码,可以时刻监控浏览器或者停下来手动操控,selenium虽然慢,可是开发效率高啊,对于不看重效率的自娱自乐的爬虫我觉得完全足够了,所以现在先用比较简单的谷歌浏览器试验一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| from bs4 import BeautifulSoup as bs from selenium import webdriver driver = webdriver.Chrome('F:\E盘文件\重要软件\chrome_drive\chromedriver_win32\chromedriver.exe') driver.maximize_window() driver.get("https://movie.douban.com/subject/26363254/comments?start=0&limit=20") driver.implicitly_wait(20) eachCommentList = [];i=0 while i<10000: new_page = driver.page_source soup = bs(new_page, 'html.parser') comment_div_lits = soup.find_all('div', class_='comment') for item in comment_div_lits: if item.find_all('p')[0].string is not None: eachCommentList.append(item.find_all('p')[0].string) element2 = driver.find_element_by_xpath("//a[@class='next']") sentinel=driver.current_url element2.click() if sentinel== driver.current_url or i>10000: st=input() if st== 'berak': break i=i+1 print(driver.current_url)
|
数据清洗
对上面得到的评论文本,我需要去其标点符号,删其语气词,取其分割位置,算其出现频数,然后才舒服。停词文档的选择很重要啊,我发现用这份停词文档处理得到的词语依然有些没有用的词,比如“都”,“还”;另外停词文件中应不应该包含标点符号,事先清洗掉标点符号的做法是出于什么理由?
你可能要先下好中文停词txt文件,可以百度之
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import re import jieba import pandas as pd import numpy def clean(result,stopwords): comments = '' for k in range(len(result)): comments = comments + (str(result[k])).strip() pattern = re.compile(r'[\u4e00-\u9fa5]+') filterdata = re.findall(pattern, comments) cleaned_comments = ''.join(filterdata) segment = jieba.lcut(cleaned_comments) words_df = pd.DataFrame({'segment': segment}) stopwords = pd.read_csv(stopwords, index_col=False, quoting=3, sep="\t", names=['stopword'], encoding='utf-8') words_df = words_df[~words_df.segment.isin(stopwords.stopword)] return words_df stopwords = 'E:\\blog\\assets\\stopwords-list\\stop_words_zh_UTF-82.txt' result2 = clean(result=eachCommentList, stopwords=stopwords) words_stat = result2.groupby(by=['segment'])['segment'].agg({"计数": numpy.size}) words_stat = words_stat.reset_index().sort_values(by=["计数"], ascending=False)
|
词云展示
用python也可以做词云,然而用R做词云感觉才更GEEK更容易更好看。顺便也可以测试一下使用python调用R语句绘图,这比调用一般的R语句又要晦涩一点。
由于wordcloud2对中文的词云支持不太好,我将目光转向了略显粗糙的第一版wordcloud。
你可能需要在RStudio中安装好对应的wordcloud包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import rpy2.robjects as robjects from rpy2.robjects import pandas2ri pandas2ri.activate() mydata=robjects.r['data.frame'](x=words_stat["segment"],y=words_stat["计数"]) robjects.globalenv['mydata']=mydata robjects.r(''' f=function(mydata) { library(wordcloud) n=ifelse(nrow(mydata)>200,200,nrow(mydata)) my_cloud=wordcloud(mydata[1:n,1],mydata[1:n,2], random.color = T,colors = c("purple","sienna","springgreen", "tomato","violetred4","seagreen3")) #my_path <- htmltools::html_print(my_cloud) # saves html in temp directory #print(my_path) # the location of the html file. } #path=f(mydata) #class(mydata) #print(mydata[1:10,1]) library(wordcloud) f(mydata) #在我的电脑上可以自动打开device窗口 ''')
|
把这个流程封装一下,以后看电影之前就可以用这个黑科技看一下电影能不能吸住你的眼球,反正又不是剧透,看完还能发个微博装装逼。:)
